package com.example.drivequickstart;

/**
 * @author aizaz.haider
 */
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

public class MainActivity extends Activity implements OnClickListener {
	static final int REQUEST_ACCOUNT_PICKER = 1;
	static final int REQUEST_AUTHORIZATION = 2;
	static final int CAPTURE_IMAGE = 3;

	private static Uri fileUri;
	private static Drive service;
	private GoogleAccountCredential credential;

	private Button btnCaptureUpload = null;
	private Button btnListFiles = null;
	private LinearLayout imageLayout = null;
	private ScrollView scrollView = null;
	private Button btnCreatePDF = null;

	private boolean isCamera = false;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		this.initXMLControls();
		this.registerClickListners();

	}

	private void initXMLControls() {
		btnCaptureUpload = (Button) findViewById(R.id.btn_camera_upload);
		btnListFiles = (Button) findViewById(R.id.btn_list_files);
		scrollView = (ScrollView) findViewById(R.id.scrollview_pics);
		imageLayout = (LinearLayout) scrollView.getChildAt(0);
		btnCreatePDF = (Button) findViewById(R.id.btn_createpdf);
	}

	private void registerClickListners() {
		btnCaptureUpload.setOnClickListener(this);
		btnListFiles.setOnClickListener(this);
		btnCreatePDF.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_camera_upload:
			isCamera = true;
			DoAuth();
			break;

		case R.id.btn_list_files:
			isCamera = false;
			DoAuth();
			imageLayout.removeAllViews();
			imageLayout.refreshDrawableState();
			break;
		case R.id.btn_createpdf:
			Intent intent = new Intent(this, PDFActivity.class);
			startActivity(intent);
			break;
		default:
			break;
		}

	}

	private void DoAuth() {
		credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
		startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
	}

	List<File> retreivedFileList = new ArrayList<File>();

	@Override
	protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
		switch (requestCode) {
		case REQUEST_ACCOUNT_PICKER:
			if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
				String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
				if (accountName != null) {
					credential.setSelectedAccountName(accountName);
					service = getDriveService(credential);
					if (isCamera) {
						startCameraIntent();
						isCamera = false;
					} else if (!isCamera) {
						new Thread(new Runnable() {

							@Override
							public void run() {

								try {
									retreivedFileList = retrieveAllFiles(service);
									for (int i = 0; i < retreivedFileList.size(); i++) {
										final int j = i;
										MainActivity.this.runOnUiThread(new Runnable() {

											@Override
											public void run() {
												ImageView iv = new ImageView(MainActivity.this);
												iv.setBackgroundResource(R.drawable.ic_launcher);

												iv.setTag(retreivedFileList.get(j).getThumbnailLink());

												new DownloadImagesTask().execute(iv);

												imageLayout.addView(iv);
												imageLayout.refreshDrawableState();
											}
										});

									}
								} catch (IOException e) {
									e.printStackTrace();
									showToast(e.getMessage());
								}

							}
						}).start();
					}

				}
			}
			break;
		case REQUEST_AUTHORIZATION:
			if (resultCode == Activity.RESULT_OK) {
				saveFileToDrive();
			} else {
				startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
			}
			break;
		case CAPTURE_IMAGE:
			if (resultCode == Activity.RESULT_OK) {
				saveFileToDrive();
			}
		}
	}

	private void startCameraIntent() {
		String mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath();
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
		fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_" + timeStamp + ".jpg"));

		Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
		startActivityForResult(cameraIntent, CAPTURE_IMAGE);
	}

	private void saveFileToDrive() {
		showToast("Uploading file in background...");
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					// File's binary content
					java.io.File fileContent = new java.io.File(fileUri.getPath());
					FileContent mediaContent = new FileContent("image/jpeg", fileContent);

					// File's metadata.
					File body = new File();
					body.setTitle(fileContent.getName());
					body.setMimeType("image/jpeg");

					File file = service.files().insert(body, mediaContent).execute();
					if (file != null) {
						showToast("Photo uploaded: " + file.getTitle());
						// startCameraIntent();
					}
				} catch (UserRecoverableAuthIOException e) {
					startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		t.start();
	}

	private Drive getDriveService(GoogleAccountCredential credential) {
		return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
	}

	public void showToast(final String toast) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
			}
		});
	}

	// ...

	/**
	 * Retrieve a list of File resources.
	 * 
	 * @param service
	 *            Drive API service instance.
	 * @return List of File resources.
	 */
	private List<File> retrieveAllFiles(Drive service) throws IOException {
		List<File> result = new ArrayList<File>();
		// Files.List request = service.files().list();
		Files.List request = service.files().list().setQ("mimeType = 'image/jpeg'");

		do {
			try {
				FileList files = request.execute();

				result.addAll(files.getItems());
				request.setPageToken(files.getNextPageToken());
			} catch (IOException e) {
				System.out.println("An error occurred: " + e);
				request.setPageToken(null);
			}
		} while (request.getPageToken() != null && request.getPageToken().length() > 0);

		return result;
	}

	/**
	 * Download a file's content.
	 * 
	 * @param service
	 *            Drive API service instance.
	 * @param file
	 *            Drive File instance.
	 * @return InputStream containing the file's content if successful, {@code null} otherwise.
	 */
	// private InputStream downloadFile(Drive service, File file) {
	// if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
	// try {
	// HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
	// return resp.getContent();
	// } catch (IOException e) {
	// // An error occurred.
	// e.printStackTrace();
	// return null;
	// }
	// } else {
	// // The file doesn't have any content stored on Drive.
	// return null;
	// }
	// }

	public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {

		ImageView imageView = null;

		@Override
		protected Bitmap doInBackground(ImageView... imageViews) {
			this.imageView = imageViews[0];
			return download_Image((String) imageView.getTag());
		}

		@Override
		protected void onPostExecute(Bitmap result) {
			imageView.setBackgroundResource(0);
			imageView.setImageBitmap(result);
		}

		private Bitmap download_Image(String url) {
			try {
				HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();
				return BitmapFactory.decodeStream(resp.getContent());
			} catch (IOException e) {
				// An error occurred.
				e.printStackTrace();
				return null;
			}
		}
	}

}
